#include <jni.h>
#include <string>
#include <android/log.h>
#define LOG_TAG  "C_TAG"
#define LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
void GetRecCode(uint8_t *RecCode, uint8_t *data, uint8_t len,uint32_t crc ) {
    uint8_t i,j;
    uint32_t poly = 0x84089604; //CRC polynom 固定 crc=0x12345678; //通讯密码，APP可修改
    for (i=0;i<len;i++) {
        crc ^= data[i];
        for (j=0; j<8; j++) {
            if (crc&1){
                crc = (crc >> 1) ^ poly;
            }else{
                crc = (crc >> 1);
            }
        }
    }
    RecCode[0] = (uint8_t)crc;
    RecCode[1] = (uint8_t)(crc>>8);
    return;
}

void CRC16(uint8_t *CRC, uint8_t* data,uint8_t len) {
    uint crc = 0x6363;
    uint8_t i, j;
    const uint poly = 0x8408; //CRC polynom 固定
    for (i=0;i<len;i++)
    {
        crc ^= data[i];
        for (j=0; j<8; j++) {
            if (crc&1)
                crc = (crc>>1) ^ poly;
            else
                crc = (crc>>1);
        }

    }
    CRC[0] = (uint8_t)crc;
    CRC[1] = (uint8_t)(crc>>8);
}
extern "C"
JNIEXPORT jintArray JNICALL
Java_com_encode_DataTools_encode(JNIEnv *env, jobject instance,
                                                      jintArray data_,jlong psd) {

    jint *data = env->GetIntArrayElements(data_, NULL);

    jsize len = env->GetArrayLength(data_) - 4;
    jint *body =  env->GetIntArrayElements(data_, 0);

    jint i = 0;
    uint8_t recCode[2];
    uint8_t bytes[len+4];
    for (; i < len; i++) {

        bytes[i] = (uint8_t)body[i];

    }
    u_int32_t crc=(long) psd;
//    LOGD("c: psd===%x\n",crc);

    GetRecCode(recCode, bytes, 13,crc);
    bytes[len] = recCode[0];
    bytes[len+1] = recCode[1];
//    LOGD("c: bytes 14,15:%x,%x",recCode[0],recCode[1]);
//    for (int i = 0;i < len + 2;i++){
//        LOGD("c: 15===%x\n",bytes[i]);
//    }



    uint8_t CRC[2];
    CRC16(CRC, bytes, 15);
    bytes[len+2] = CRC[0];
    bytes[len+3] = CRC[1];
//    for (int i = 0;i < len + 4;i++){
//        LOGD("c: 16===%x\n",bytes[i]);
//    }


    uint32_t Xor;
    Xor = CRC[0]^CRC[1];
    int j = 0;
    for (j=0; j < len+2; j++) {
        bytes[j] ^= Xor;
        Xor += 65;
    }

//    for (int i = 0;i < len+4;i++){
//        LOGD("c: 0x%x , %d\n",bytes[i],bytes[i]);
//    }

    jint* arr = new jint[len + 4];

    for (int i = 0; i < len + 4; ++i) {
        arr[i] = bytes[i];
    }
    env->ReleaseIntArrayElements(data_, arr, 0);
    return  data_;
}

extern "C"
JNIEXPORT jlong JNICALL
Java_com_encode_DataTools_phoneNumber__Lint_3_093_2(JNIEnv *env,
                                                                              jobject instance,
                                                                              jintArray data_) {
    jint *data = env->GetIntArrayElements(data_, NULL);
    jsize len = env->GetArrayLength(data_);
    jint *body =  env->GetIntArrayElements(data_, 0);

    uint64_t phone=0x00;
    for (int i = 0;i < len;i++){
//        LOGD("c: 16===%x\n",body[i]);
        phone|=((uint64_t)body[i])<<(i*8);
    }
//    LOGD("phone number %lu",phone);
    env->ReleaseIntArrayElements(data_, data, 0);
    return (long long) phone;
}